﻿using System;
using System.Collections.Generic;
//using System.Linq;
using System.Text;
using System.Drawing;

namespace WellLogShower
{   
    public class WellDrawerImpl:WellDrawer
    {
        Rectangle RectF2Rect(RectangleF rectF)
        {
            return new Rectangle((int)rectF.X, (int)rectF.Y, (int)rectF.Width, (int)rectF.Height);
        }
        public void DrawDepthHead(Graphics g, RectangleF rect, LogData logData, Color clr)
        {
            Pen headerLine = new Pen(Color.Black, 1);
            g.DrawRectangle(headerLine, RectF2Rect(rect));

            Font curveFont = new Font("宋体", 10);
            Brush blackBrush = new SolidBrush(Color.Black);
            g.DrawString(logData.Name, curveFont, blackBrush, rect.X + rect.Width / 2 - 15, rect.Y + 3);
            g.DrawString(logData.Unit, curveFont, blackBrush, rect.X + rect.Width / 2 - 15, rect.Y + rect.Height / 2.0F + 3);
        }

        int MakeDepthType(double deep)
        {
            int deep8 = (int)(deep * 8);
            if (deep8 % 40 == 0)
            {
                return 2;
            }
            if (deep8 % 8 == 0)
            {
                return 1;
            }
            return 0;
        }

        public void DrawDepthTrack(Graphics g, RectangleF rect, LogData logData, Color clr)
        {
            Pen blackLine = new Pen(Color.Black, 1);
            g.DrawRectangle(blackLine, RectF2Rect(rect));

            Font font = new Font("宋体", 10);
            Brush brush = new SolidBrush(Color.Black);

            if (logData.Data.Count >= 2)
            {
                RectangleF curveRect = rect;
                curveRect.Height -= 10;

                int dataCount = logData.Data.Count;
                int count = dataCount > curveRect.Height ? (int)curveRect.Height : dataCount;

                for (int i = 0; i < count; i++)
                {
                    double curDepth = logData.Data[dataCount - i - 1];
                    float curX = curveRect.X;
                    float curY = curveRect.Y + count - i;
                    //PointF curPoints = new PointF(curveRect.X + curveRect.Width, curveRect.Y + count - i);
                    int depthType = MakeDepthType(curDepth);
                    switch (depthType)
                    {
                        case 2:
                            g.DrawString(curDepth.ToString(),font ,brush, curX , curY);
                            g.DrawLine(blackLine, curX + curveRect.Width, curY, curX + curveRect.Width - 20,curY);
                            break;
                        case 1:
                            g.DrawLine(blackLine, curX + curveRect.Width, curY, curX + curveRect.Width - 10,curY);
                            break;
                        case 0:
                            break;
                        default: 
                            break;;
                    }
                }
            }

        }

        public void DrawHeader(Graphics g, RectangleF rect, LogData logData,Color clr)
        {
            Pen headerLine = new Pen(Color.Black, 1);
            g.DrawRectangle(headerLine, RectF2Rect(rect));

            Pen curveLine = new Pen(clr, 1);
            g.DrawLine(curveLine
                        , rect.X + rect.Width * 0.1F
                        , rect.Y + rect.Height / 2.0F
                        , rect.X + rect.Width * 0.9F
                        , rect.Y + rect.Height / 2.0F);

            Font curveFont = new Font("宋体", 10);
            Brush blackBrush = new SolidBrush(Color.Black);
            g.DrawString(logData.Name, curveFont, blackBrush, rect.X + rect.Width / 2 - 15, rect.Y + 3);
            g.DrawString(logData.Unit, curveFont, blackBrush, rect.X + rect.Width / 2 - 15, rect.Y + rect.Height / 2.0F + 3);
        }

        PointF[] CalcCurvePoints(LogData logData,RectangleF curveRect)
        {
            int dataCount = logData.Data.Count;
            int count = dataCount > curveRect.Height ? (int)curveRect.Height : dataCount;

            double a = 1.0;
            double min = LogData.Min(logData.Data);
            double max = LogData.Max(logData.Data);
            if (logData.Data.Count != 0)
            {
                a = curveRect.Width / (max - min < 0.0001 ? 1 : max -min);
            }
            
            PointF[] points = new PointF[count];
            for (int i = 0; i < count; i++)
            {
                double val = logData.Data[dataCount - i - 1] - min;
                points[i] = new PointF(curveRect.X + (float)(val * a), curveRect.Y + count - i);
            }
            return points;
        }

        public void DrawCurve(Graphics g, RectangleF rect, LogData logData,Color clr)
        {
            Pen blackLine = new Pen(Color.Black, 1);
            g.DrawRectangle(blackLine, RectF2Rect(rect));

            if (logData.Data.Count >= 2)
            {
                RectangleF curveRect = rect;
                curveRect.Height -= 10;
                PointF[] points = CalcCurvePoints(logData,curveRect);

                Pen curveLine = new Pen(clr, 1);
                g.DrawLines(curveLine, points);
            }
        }

        public void Draw(Graphics g, RectangleF rect, WellData wellData)
        {
            //0.01毫米的模式
            //g.PageUnit = GraphicsUnit.Millimeter;
            //g.PageScale = 0.01F;

            int MaxCurveCount = 6;
            Color[] colors = new Color[MaxCurveCount];
            colors[0] = Color.Pink;
            colors[1] = Color.Blue;
            colors[2] = Color.Red;
            colors[3] = Color.DarkRed;
            colors[4] = Color.DarkSeaGreen;
            colors[5] = Color.DarkOrange;

            Brush whiteBrush = new SolidBrush(Color.White);
            Brush blackBrush = new SolidBrush(Color.Black);
            Pen frameLine = new Pen(Color.Black, 2);
            Font titleFont = new Font("宋体", 15);
            Font curveFont = new Font("宋体", 5);

            //填充白色底色
            g.FillRectangle(whiteBrush, rect);


            SpaceAllocater allocater = new SpaceAllocater(rect, MaxCurveCount);

            //框架线
            g.DrawRectangle(frameLine, RectF2Rect(allocater.FrameRect()));

            //井头
            RectangleF titleRect = allocater.TitleRect();
            g.DrawString(wellData.WellName, titleFont, blackBrush, titleRect.X + titleRect.Width / 2 - 20, titleRect.Y);

            //道头
            int logSize = wellData.LogData.Length;
            List<RectangleF> headRects = allocater.HeaderRect();
            DrawDepthHead(g, headRects[0], wellData.LogData[0], colors[0]);
            for (int i = 1; i < MaxCurveCount && i < logSize; i++)
            {
                RectangleF headerRect = headRects[i];
                DrawHeader(g, headerRect, wellData.LogData[i],colors[i]);
            }

            //曲线
            List<RectangleF> curveRects = allocater.CurveRect();
            DrawDepthTrack(g, curveRects[0], wellData.LogData[0], colors[0]);
            for (int i = 1; i < MaxCurveCount && i < logSize; i++)
            {
                RectangleF curveRect = curveRects[i];
                DrawCurve(g, curveRect, wellData.LogData[i],colors[i]);
            }
        }
    }
}
